﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FunctionGraph
{
    public class SolutionEvaluationVisitor : ExpressionVisitor<bool>
    {
        internal Interval x, y;
        internal BinaryCodeEvaluator[] evaluators;
        public override bool VisitBinarySolutionEval(BinarySolutionEvaluationNode node)
        {
            switch (node.Operator)
            {
                case MathOperator.Or:
                    return node.Left.Accept(this) || node.Right.Accept(this);
                case MathOperator.And:
                    return node.Left.Accept(this) && node.Right.Accept(this);
            }
            return false;
        }

        public override bool VisitExprSolutionEvaluationNode(ExprSolutionEvaluationNode node)
        {
            var eval = evaluators[node.EvaluatorId];
            var v0 = eval.Evaluate(x, y);
            if (v0.Intervals.Count != 1)
                return false;
            if (!v0.Intervals[0].Cont0)
                return false;
            if (!v0.Intervals[0].Def0)
                return false;
            var v1 = eval.Evaluate(new Interval(x.Val0, x.Val0), new Interval(y.Val0, y.Val0));
            var v2 = eval.Evaluate(new Interval(x.Val1, x.Val1), new Interval(y.Val1, y.Val1));
            if (v1.NotEmpty && v2.NotEmpty && v1.Intervals[0].Val0 * v2.Intervals[0].Val0 <= 1e-9)
                return true;
            var v3 = eval.Evaluate(new Interval(x.Val1, x.Val1), new Interval(y.Val0, y.Val0));
            var v4 = eval.Evaluate(new Interval(x.Val0, x.Val0), new Interval(y.Val1, y.Val1));
            if (v3.NotEmpty && v4.NotEmpty && v3.Intervals[0].Val0 * v4.Intervals[0].Val0 <= 1e-9)
                return true;
            return false;
        }

        public override bool VisitConstant(ConstantNode constantNode)
        {
            throw new NotImplementedException();
        }

        public override bool VisitVariable(VariableNode variableNode)
        {
            throw new NotImplementedException();
        }

        public override bool VisitBinary(BinaryNode binaryNode)
        {
            throw new NotImplementedException();
        }

        public override bool VisitUnary(UnaryNode unaryNode)
        {
            throw new NotImplementedException();
        }
    }
}
